<?php

abstract class ResourceList extends Node
{

    private $numPorPaginaIni;
    private $classEltosIni;

    /**
     * Número de objetos item por página
     * @access private
     * @var int
     */
    protected $numPorPagina = 10;

    /**
     * Número de páginas del resultado
     * @access private
     * @var int
     */
    protected $numPaginas = null;

    /**
     * Número de objetos Resource del resultado
     * @access private
     * @var int
     */
    protected $numItems = null;

    /**
     * Página actual
     * @access private
     * @var int
     */
    protected $pagina = 1;

    /**
     * Índice de la columna (según se han definido en {@link DrawerList::__construct()}) que da orden a la lista.
     * @access private
     * @var int
     */
    protected $order = 1;
    protected $hoyDia;
    protected $hoyMes;
    protected $hoyAnho;

    /**
     * Clase de los elementos de la lista
     * @access private
     * @var string
     */
    private $classEltos;

    /**
     * Condiciones que deben cumplir cualquier elemento de la lista
     * @access private
     * @var string
     */
    protected $where;

    /**
     * Condiciones que restringen la lista de resultados
     * @access private
     * @var string
     */
    private $andWhere = '';

    /**
     * Array con los distintos orders que admite la lista
     * @var array
     * @access private
     */
    private $orders = array( );

    /**
     * Conjunto de roles usados para obtener la lista
     * @var array
     * @access private
     */
    private $roles = null;

    /**
     * Constructor de la clase.
     * @param string $searchclass Clase de los objetos que se van a representar en la lista
     * @param string $where Condiciones básicas que debe cu,plir la lista
     * @param array $orders Vector con los distintos ordenes que puede desplegar la lista
     */
    function __construct( $searchclass, $numperpage, $where, $orders )
    {
        $fecha = getdate();
        $this->hoyDia = $fecha[ 'mday' ];
        $this->hoyMes = $fecha[ 'mon' ];
        $this->hoyAnho = $fecha[ 'year' ];

        $this->numPorPaginaIni = $numperpage;
        $this->classEltosIni = $searchclass;

        $this->numPorPagina = $numperpage;
        $this->classEltos = $searchclass;
        $this->andWhere = $where;

        $i = 1;
        foreach ( $orders as $k => $ord ) {
            $this->orders[ $i ] = $ord;
            $this->orders[ -1 * $i ] = $ord . ' DESC';
            ++$i;
        }
        $this->order = -1;
    }

    /**
     * Establece la página de la lista que se va a mostrar
     * @param int $p Página
     */
    function setPage( $p )
    {
        if ( $p < 1 ) $p = 1;
        $this->pagina = ( int ) $p;
    }

    /**
     * Selecciona el índice (dentro del array que se pasa al constructor) del orden que se va a utilizar en la lista
     * @param int $orden Índice de la columna que va a establecer el orden. El índice puede ser negativo si queremos establecer el orden inverso.
     */
    function setOrder( $order )
    {
        $this->order = ( int ) $order;
    }

    function numPerPage( $num )
    {
        $this->numPorPagina = ( int ) $num;
    }

    function setNumItems( $total )
    {
        $this->numItems = ( int ) $total;
    }

    function setRoles( $roles )
    {
        $this->roles = $roles;
    }

    /*
      function setNum($num){
      $this->numPaginas=$num;
      }
     */

    /**
     * Destaca un elemento  de la lista.
     * @param mixed $id Identificador del objeto
     */
    function emphasize( $ids )
    {
        //DEBERÍA SOLO COGER AQUELLOS QUE TENGA
        foreach ( $ids as $id ) {
            $o = Node::getInstance( $this->classEltos, $id );
            if ( $o ) $o->emphasize();
        }
    }

    /**
     * Restricciones a la lista de objetos.
     * @param string $where Condición SQL que se va a añadir a la consulta que genera la lista mediante un AND
     */
    protected function andWhere( $where )
    { //este no es el where del constructor sino un where a mayores
        if ( !empty( $where ) ) {
            if ( empty( $this->where ) ) $this->where = '(' . $where . ')';
            else $this->where.=' AND (' . $where . ')';
        }
    }

    /**
     * Definimos el método evalue para que actualice la lista después de los métodos que ha recibido
     * @return boolean
     */
    function fill()
    {

        if ( !empty( $this->where ) && !empty( $this->andWhere ) )
                $where = $this->where . ' AND ' . $this->andWhere;
        else $where = $this->where . $this->andWhere;

        //$this->childNodes=array();///?????????????????????????????????????

        if ( !empty( $this->numItems ) && $this->pagina > ceil( $this->numItems / $this->numPorPagina ) )
                $this->pagina = ceil( $this->numItems / $this->numPorPagina );

        $eltos = array( );
        $this->_setNumItems(
                Node::getArray(
                        $this->classEltos, $eltos, $where,
                        $this->orders[ $this->order ], $this->numPorPagina,
                        ($this->pagina - 1) * $this->numPorPagina,
                        $this->numItems, $this->roles
        ) );

        if ( $this->numPorPagina == 0 ) $this->numPaginas = 1;

        else if ( $this->numItems == 0 ) $this->numPaginas = 1;
        else $this->numPaginas = ceil( $this->numItems / $this->numPorPagina );

        if ( $this->pagina > $this->numPaginas ) {

            $this->pagina = $this->numPaginas;

            $this->_setNumItems(
                    Node::getArray(
                            $this->classEltos, $eltos, $where,
                            $this->orders[ $this->order ], $this->numPorPagina,
                            ($this->pagina - 1) * $this->numPorPagina,
                            $this->numItems, $this->roles
            ) );
        }

        //Ahora, si mi pagina es superior a la que tengo

        foreach ( $eltos as $e ) $this->appendChild( $e );


        return true;
    }

    function handleGET( Event $e )
    {

        switch ( $e->tag ) {
            case 'pagina':
                $this->_setPage( $_REQUEST[ 'pagina' ] );
                $e->cancelBubble();
                break;

            case 'orden':
                $this->_setOrder( $_REQUEST[ 'orden' ] );
                $e->cancelBubble();
                break;

            case 'paginacion':
                $this->_numPerPage( $_REQUEST[ 'paginas' ] );
                $e->cancelBubble();
                break;
        }
    }

}

?>